#include "task_main.h"
#include <stdio.h>
#include <stdarg.h>
#include "strutil.hpp"
#include "stimer.h"
#include "zh_iSwitch.h"
#include "adc.h"
#include "log.h"
#include "hrtim.h"
#include "bsp_hrtimer.h"
#include "bsp_protocol.hpp"
#include "bsp_wifi.h"
#include "wifi_connect.hpp"
#include "dcdc.hpp"
#include "ITM.h"
#include "comp.h"
#include "dac.h"

#define LOG_MAIN(TAG, str, ...) Queue_Printf(&htx1, str, ##__VA_ARGS__)
#define TASK_BUFFER_SIZE 8
stimer_task_t task_buffer[TASK_BUFFER_SIZE];
uint16_t TaskInputID, TaskOutputID, TaskMsgHandleID, TaskDisplayID;
bsp_timeMesure_t taskOutputTime, taskMsgHandleTime;
uint32_t tasktimebuf;
float tasktime;
// uint32_t Key_Value = 0;
// char keyChar = 0;
uint8_t LED_RUN_State = 0;
uint8_t LED_STA_State = 0;
uint8_t LED_ERR_State = 0;
extern uint16_t ADC1Buf[ADC1_BUF_SIZE];
extern uint16_t ADC2Buf[ADC2_BUF_SIZE];

int user_esp_01s_rx_callback(const uint8_t *data, uint16_t len);
wifiConnect wifiJAP(&wifi_module, user_esp_01s_rx_callback);

int taskTimeCounter;

void task_connect_wifi_start(const void *arg)
{
    wifiJAP.start_join_ap("DCDC", "00000000");
}

void user_task_init(void)
{
    stimer_init(task_buffer, TASK_BUFFER_SIZE);

    // stimer_set_task_start_hook(user_task_start_hook);
    // stimer_set_task_end_hook(user_task_end_hook);
    //	TaskInputID = stimer_create_task(TaskInput, 10, 1, 1);
    TaskOutputID = stimer_create_task(TaskOutput, 10, 2, 1);
    //	TaskMsgHandleID = stimer_create_task(TaskMsgHandle, 1, 1, 1);
    //	TaskDisplayID = stimer_create_task(TaskDisplay, 100, 0, 1);
    TaskBuzzerID = stimer_create_task(TaskBuzzer, 50, 1, 1);
}
/* USER CODE BEGIN Header_TaskInit */
/**
 * @brief  Function implementing the InitTask thread.
 * @param  argument: Not used
 * @retval None
 */
/* USER CODE END Header_TaskInit */
void TaskInit(void const *argument)
{
    /* USER CODE BEGIN TaskInit */
    //	const uint8_t logo[] = {"STM32&CLLC"};
    log_set_level(LOG_LEVEL_NONE);
    DCDC_MOS_DISABLE();
    board_base_init(); // UART, TIM, LED
    bsp_HRTIM_Init();
    user_task_init();
    HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);
    HAL_ADCEx_Calibration_Start(&hadc2, ADC_SINGLE_ENDED);
    HAL_ADC_Start_DMA(&hadc1, (uint32_t *)&ADC1Buf, ADC1_BUF_SIZE);
    HAL_ADC_Start_DMA(&hadc2, (uint32_t *)&ADC2Buf, ADC2_BUF_SIZE);
    // HAL_ADC_Start(&hadc1);
    // HAL_ADC_Start(&hadc2);
    HAL_TIM_Base_Start_IT(&htim15);
//    __HAL_TIM_DISABLE_IT(&htim15, TIM_IT_UPDATE);
	// HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_2, DAC_ALIGN_12B_R, 0);
    // HAL_DAC_SetValue(&hdac2, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 0);
    // HAL_DAC_Start(&hdac1, DAC_CHANNEL_2);
    // HAL_DAC_Start(&hdac2, DAC_CHANNEL_1);

//    HAL_COMP_Start_IT(&hcomp2);
//    HAL_COMP_Start_IT(&hcomp4);
    dcpower.fan_init();
    wifiJAP.start_join_ap("DCDC", "00000000");
    Beep(200);

    // stimer_task_oneshot(task_connect_wifi_start, 3000, 1, NULL);
    //    HAL_TIM_Base_Start(&htim15);
    //	  stimer_task_delay_start(TaskInputID, STIMER_TASK_LOOP, (void*)"TaskInput", 0);
    stimer_task_delay_start(TaskOutputID, STIMER_TASK_LOOP, (void*)"TaskOutput", 5);
    //	  stimer_task_delay_start(TaskMsgHandleID, STIMER_TASK_LOOP, (void*)"TaskMsgHandle", 10);
    //    stimer_task_delay_start(TaskDisplayID, STIMER_TASK_LOOP, (void*)"TaskDisplay", 20);
    
    /* USER CODE END TaskInit */
}

/* USER CODE BEGIN Header_TaskInput */
/**
 * @brief  Function implementing the InputTask thread.
 * @param  argument: Not used
 * @retval None
 * @note TODO: 定时器触发ADC采样,在采样完成中断中通知本任务处理数据，
 *             处理完成后本任务通知TaskOutput进行反馈调节
 */
/* USER CODE END Header_TaskInput */
void TaskInput(void const *argument)
{
    /* USER CODE BEGIN TaskInput */
    // LOG_MAIN(LOGTAG, "TaskInput\n");
    /* Infinite loop */
    //	uint32_t Key_Input = 0;
    //	Key_Input |= KEYx_Read(KEY0, 0);
    //	Key_Input |= KEYx_Read(KEY1, 1);
    //	Key_Value = iSWx_Handler(Key_Input);


    /* USER CODE END TaskInput */
}

/* USER CODE BEGIN Header_TaskOutput */
/**
 * @brief Function implementing the OutputTask thread.
 * @param argument: Not used
 * @retval None
 * @note 本任务运行一个状态机，由TaskInput任务、外部中断、外部指令通知本
 *       任务进行输出控制，其他外部外部事件也可以通知本任务
 */
/* USER CODE END Header_TaskOutput */
void TaskOutput(void const *argument)
{
    /* USER CODE BEGIN TaskOutput */
    // LOG_MAIN(LOGTAG, "TaskOutput\n");

    /* Infinite loop */
    static uint32_t cnt = 0;

//    bsp_HPMesureTimeStart(&taskOutputTime);
    LED_RUN_State = 2;

	cnt++;
	if (cnt % 50 == 0) // 500ms
	{

		cnt = 0;
		// HAL_PWR_EnterSLEEPMode();
		if (Pinx_ORead(PWM_HV_EN1) == 0 || Pinx_ORead(PWM_LV_EN1) == 0)
		{
			LEDx_Write(LED_STA, 1);
		}
		else
		{
			LEDx_Write(LED_STA, 0);
		}

		switch (LED_RUN_State)
		{
		case 0:
			LEDx_Write(LED_RUN, 0);
			break;
		case 1:
			LEDx_Write(LED_RUN, 1);
			break;
		case 2:
			LEDx_Togger(LED_RUN);
			break;
		default:
			LED_RUN_State = 0;
			break;
		}
	}
    
    tasktime = DWT_Time_Measure(&tasktimebuf);
    bsp_HPMesureTime(&taskOutputTime);
    /* USER CODE END TaskOutput */
}

#if 1
/* USER CODE BEGIN Header_TaskMsgHandle */
/**
 * @brief Function implementing the MsgHandlerTask thread.
 * @param argument: Not used
 * @retval None
 * @note 本任务由UART中断和CAN中断唤醒，处理外部指令信息，根据指令可以通知其他任务
 */
/* USER CODE END Header_TaskMsgHandle */
void TaskMsgHandle(void const *argument)
{
    /* USER CODE BEGIN Task_MsgHandle */
    uint8_t *pdata = NULL;
    UART_HandleTypeDef *phuart = NULL;
    uint32_t size = 0;
//    uint32_t taskNotify;
//    TickType_t state;
//	  uint8_t buff[128];

    /* Infinite loop */
 
//        state = xTaskNotifyWait(0xffffffffUL,
//                                0,
//                                &taskNotify,
//                                portMAX_DELAY);
//    bsp_HPMesureTimeStart(&taskMsgHandleTime);
//    bsp_HPMesureTime(&taskMsgHandleTime);
    if (hrx1.huart->ErrorCode)
    {
        User_UART_Receive_Start(&hrx1); //开启下一轮接收
    }
    // 获取任务通知值并清空
    if (hrx1.rxCpltFlag) /* 读到了数据 */
    {
        hrx1.rxCpltFlag = 0;
        phuart = &huart1;
        pdata = UART_GetRxData(&hrx1);
        size = UART_GetRxSize(&hrx1);
        if (wifiJAP.get_state())
        {
            UARTx_Printn(&huart1, (uint8_t*)"[RX1]", 5);
            UARTx_Printn(&huart1, pdata, size);
            UARTx_Printn(&huart1, (uint8_t*)"\n\r", 2);
        }

        UARTx_Printn(&huart3, (uint8_t *)"[RX1]", 5);
        UARTx_Printn(&huart3, pdata, size);
        UARTx_Printn(&huart3, (uint8_t *)"\n\r", 2);
        // UARTx_Printn(&huart2, pdata, size);
        if (size)
        {
            bsp_wifi_module_callback(pdata, size);
        }
    }
    if (hrx3.rxCpltFlag) /* 读到了数据 */
    {
        hrx3.rxCpltFlag = 0;
        phuart = &huart3;
        pdata = UART_GetRxData(&hrx3);
        size = UART_GetRxSize(&hrx3);
        UARTx_Printn(&huart3, (uint8_t *)"[RX3]", 5);
        UARTx_Printn(&huart3, pdata, size);
        UARTx_Printn(&huart3, (uint8_t *)"\n\r", 2);
        if (size > 2 && pdata[0] == 'A' && pdata[1] == 'T')
        {
            // 转发AT指令
            UARTx_Printn(&huart1, pdata, size);
        }
        // UARTx_Printn(&huart2, pdata, size);
    }
    if (size != 0)
    {
        SYS_CMD(phuart, pdata, size);
    }
        
    
    /* USER CODE END Task_MsgHandle */
}

/*
 * 外部指令处理
*/
int user_esp_01s_rx_callback(const uint8_t *data, uint16_t len)
{
    //	uint8_t *p = NULL;
    // Beep(50);
    if (len < 10)
    {
        return 0;
    }
    // 处理电脑发过来的数据

    return 0;
}
#endif

/**
  * @brief  Period elapsed callback in non-blocking mode
  * @param  htim TIM handle
  * @retval None
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if (htim == &htim15)
	{
        dcpower.reflash_input();
		dcpower.ex_regulator_serve();
	}

}


/**
  * @brief  Comparator trigger callback.
  * @param  hcomp  COMP handle
  * @retval None
  */
void HAL_COMP_TriggerCallback(COMP_HandleTypeDef *hcomp)
{
    if (hcomp == &hcomp2) //LV
    {
        // Beep(1000);
    }
    if (hcomp == &hcomp4) //HV
    {
        // Beep(1000);
    }

}
